#include <avr/io.h>
#include <avr/iom644.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include <string.h>
#include "usart_utils.h"

unsigned int countvect[8] = {0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C};
int show = 0;


void			process_input();
void			show_counter(int index);
void			show_all_counter();
void			EEPROM_write(unsigned int uiAddress, unsigned char ucData);
unsigned char	EEPROM_read(unsigned int uiAddress);

int
main(void) {

	DDRB = 0xFF;

	USART_Init(25);

	PCICR = (1<<PCIE0);
	PCMSK0 = 0xFF;

	sei();

	while(1) {
		process_input();
		PORTB = ~(EEPROM_read(countvect[show]));
	}
}

void
process_input() {

	int i = 0;
	char aux = 0;
	char buffer[30] = {0};

	do {
		aux = USART_Receive();
		USART_Transmit(aux);
		buffer[i] = aux;
		i++;
	} while (aux != '\r');

	buffer[i-1] = 0;

	USART_Transmit('\n');

	if(strcmp(buffer,"show 0") == 0) {
		show_counter(0);
	}
	else if(strcmp(buffer,"show 1") == 0) {
		show_counter(1);
	}
	else if(strcmp(buffer,"show 2") == 0) {
		show_counter(2);
	}
	else if(strcmp(buffer,"show 3") == 0) {
		show_counter(3);
	}
	else if(strcmp(buffer,"show 4") == 0) {
		show_counter(4);
	}
	else if(strcmp(buffer,"show 5") == 0) {
		show_counter(5);
	}
	else if(strcmp(buffer,"show 6") == 0) {
		show_counter(6);
	}
	else if(strcmp(buffer,"show 7") == 0) {
		show_counter(7);
	}
	else if(strcmp(buffer,"show a") == 0) {
		show_all_counter();
	}
	else if(strcmp(buffer,"display 0") == 0) {
		show = 0;
	}
	else if(strcmp(buffer,"display 1") == 0) {
		show = 1;
	}
	else if(strcmp(buffer,"display 2") == 0) {
		show = 2;
	}
	else if(strcmp(buffer,"display 3") == 0) {
		show = 3;
	}
	else if(strcmp(buffer,"display 4") == 0) {
		show = 4;
	}
	else if(strcmp(buffer,"display 5") == 0) {
		show = 5;
	}
	else if(strcmp(buffer,"display 6") == 0) {
		show = 6;
	}
	else if(strcmp(buffer,"display 7") == 0) {
		show = 7;
	}
	else {
		USART_Send_String("Comando no valido.\n\r");
	}
}

void
show_counter(int index) {

	int value = 0;
	char buffer[30] = {0};
	value = EEPROM_read(countvect[index]);
	sprintf(buffer, "Port: %d Cantidad: %d\n\r", index, value);
	USART_Send_String(buffer);
}

void
show_all_counter() {

	int i, value = 0;
	char buffer[30] = {0};

	for (i=0; i<8; i++){
		value = EEPROM_read(countvect[i]);
		sprintf(buffer, "Port: %d Cantidad: %d\n\r", i, value);
		USART_Send_String(buffer);
	}
}

void EEPROM_write(unsigned int uiAddress, unsigned char ucData) {

	/* Wait for completion of previous write */

	while(EECR & (1<<EEPE)) {
		;
	}

	/* Set up address and Data Registers */

	EEAR = uiAddress;
	EEDR = ucData;

	/* Write logical one to EEMPE */

	EECR |= (1<<EEMPE);

	/* Start EEPROM write by setting EEPE */

	EECR |= (1<<EEPE);
}

unsigned char EEPROM_read(unsigned int uiAddress) {

	/* Wait for completion of previous write */

	while(EECR & (1<<EEPE)) {
		;
	}

	/* Set up address register */

	EEAR = uiAddress;

	/* Start EEPROM read by writing EERE */

	EECR |= (1<<EERE);

	/* Return data from Data Register */

	return EEDR;
}

SIGNAL(PCINT0_vect) {

	unsigned char aux;
	int i, value = 0;

	aux = ~PINA;

	for (i=0; i<8; i++) {
		if (aux & (1<<i)){
			value = EEPROM_read(countvect[i]);
			value = value + 1;
			EEPROM_write(countvect[i], value);
		}
	}

	_delay_ms(100);
}
